package com.benchmark.springboot.controller;

import com.power.common.model.CommonResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * ThreadLocal使用测试
 * @author yu 2020/11/05
 */
@RestController
@RequestMapping("threadLocal")
public class ThreadLocalController {
    private final static ThreadLocal<Integer> CURRENT_USER = ThreadLocal.withInitial(()->null);

    /**
     * ThreadLocal错误使用
     * @apiNote 测试该用例是请将tomcat最大线程设置为1，因为tomcat线程池原理，
     * 不显示的清空ThreadLocal就会导致数据旧线程的数据。
     * @param userId 用户id
     * @return
     */
    @GetMapping("wrong/{userId}")
    public CommonResult<Map<String,String>> wrong(@PathVariable Integer userId){
        String before = Thread.currentThread().getName()+":"+CURRENT_USER.get();
        CURRENT_USER.set(userId);
        String after = Thread.currentThread().getName()+":"+CURRENT_USER.get();
        Map<String,String> map = new HashMap<>();
        map.put("before",before);
        map.put("after",after);
        return CommonResult.ok().setResult(map);
    }

    /**
     * ThreadLocal正例使用
     * @apiNote 使用ThreadLocal remove方法避免在线程池场景中用户数据混乱，这样before才会始终为空
     * @param userId 用户id
     * @return
     */
    @GetMapping("right/{userId}")
    public CommonResult<Map<String,String>> right(@PathVariable Integer userId){
        String before = Thread.currentThread().getName()+":"+CURRENT_USER.get();
        CURRENT_USER.set(userId);
        Map<String,String> map = new HashMap<>();
        try {
            String after = Thread.currentThread().getName()+":"+CURRENT_USER.get();
            map.put("before",before);
            map.put("after",after);
        }finally {
            CURRENT_USER.remove();
        }
        return CommonResult.ok().setResult(map);
    }

}
